﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework;

namespace DARE
{
    /// <summary>
    /// It represents an entity that regroups animations registered by name in a dictionnary.
    /// </summary>
    /// <example>
    /// <code>
    /// CSprite spr = new CSprite("ship", m_render);
    /// CAnimationState animState = new CAnimationState(CResourceMgr.Load<Texture2D>("walksequence_spritesheet"), new Rectangle(0, 0, 240, 295));
    /// animState.AddState(new Rectangle(240, 0, 240, 295));
    /// animState.AddState(new Rectangle(480, 0, 240, 295));
    /// spr.AddAnimationState("Idle", animState);
    /// </code>
    /// </example>
    public class CSprite: AEntity
    {
 
        #region fields

        private Rectangle m_rect;
        private bool m_isAnimated;
        private Texture2D m_texture;
        private CAnimationState m_currentAnimation;
        private Dictionary<string, CAnimationState> m_animations;
        private Rectangle m_subRect;

        #endregion

        #region properties

        public Texture2D Texture { get { return m_texture; } set { m_texture = value; } }

        #endregion

        #region ctor

        public CSprite(string name, CRender2D render2D)
            : this(name, render2D, null)
        {

        }

        public CSprite(string name, CRender2D render2D, AEntity parent)
            : base(name, render2D, parent)
        {
            m_animations = new Dictionary<string, CAnimationState>();
        }


        #endregion

        #region methods

        public void StartAnimation(string name)
        {
            if (m_currentAnimation != null)
                m_currentAnimation.Start();
            m_currentAnimation = m_animations[name];
            m_currentAnimation.Start();
            m_subRect = m_currentAnimation.GetCurrentAnimationState();
            m_texture = m_currentAnimation.SpriteSheet;
        }

        public override AEntity Clone(string name)
        {
            return Clone(name, null);
        }

        public override AEntity Clone(string name, AEntity parent)
        {
            CSprite sprite = new CSprite(name, m_render);
            sprite.Parent = parent;
            sprite.m_children = new Dictionary<string, AEntity>();
            foreach (AEntity child in m_children.Values)
                sprite.m_children.Add(child.Name, child.Clone(child.Name, sprite));
            sprite.m_isAnimated = m_isAnimated;
            sprite.Position = m_position;
            sprite.m_rect = m_rect;
            sprite.m_animations = m_animations;
            return sprite;
        }

        public CSprite AddAnimationState(string name, CAnimationState animationState)
        {
            m_animations.Add(name, animationState);
            if (m_animations.Count == 1)
            {
                m_currentAnimation = m_animations.First().Value;
                m_rect = m_subRect = m_currentAnimation.GetCurrentAnimationState();
            }
            m_isAnimated = true;
            return this;
        }

        public CSprite RemoveAnimationState(string name)
        {
            m_animations.Remove(name);
            if (m_animations.Count <= 1)
                m_isAnimated = false;
            return this;
        }

        public override void Update(GameTime gameTime)
        {
            if (m_isAnimated && m_currentAnimation.IsStarted)
            {
                m_subRect = m_currentAnimation.GetAnimationState(gameTime);
                m_texture = m_currentAnimation.SpriteSheet;
            }
            else
            {
                m_subRect = m_currentAnimation.GetCurrentAnimationState();
                m_texture = m_currentAnimation.SpriteSheet;
            }
            //foreach (AEntity entity in m_children.Values)
            //    entity.Update(gameTime);
        }

        public override void Draw(GameTime gameTime)
        {
            m_rect = new Rectangle((int)m_position.X, (int)m_position.Y, (int)m_size.X, (int)m_size.Y);
            CDare.Instance.SpriteBatch.Draw(m_currentAnimation.SpriteSheet, m_rect, m_subRect, Color.White);
            //foreach (AEntity entity in m_children.Values)
            //    entity.Draw(gameTime);
        }

        #endregion
    }
}
